<?php

namespace App\Models;

use App\Constants\AssetLogType;
use App\Exceptions\ApiException;
use App\Services\QuotesService;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Support\Facades\DB;

/**
 * This is the model class for table "user_assets"
 *
 * @property string $id
 * @property string $uid 用户ID
 * @property string $symbol 币种标记
 * @property string $balance 余额
 * @property string $balance_lock 锁定余额
 * @property string $freeze_balance 委托冻结
 * @property string $used_balance 持仓保证金
 * @property string $freeze_all 冻结金额
 * @property string $deposit_history 充值历史
 * @property string $created_at 创建时间
 * @property string $updated_at 更新时间
 */
class UserAsset extends BaseModel
{
    use HasDateTimeFormatter;

    protected $table = 'user_assets';
    protected $guarded = [];

    public function user()
    {
        return $this->belongsTo(User::class, 'uid', 'id');
    }

    /**
     * @param $uid
     * @param $symbol
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null|UserAsset
     * @throws \App\Exceptions\CustomException
     */
    public function getAsset($uid, $symbol)
    {
        $assert = self::query()->firstOrCreate([
            'uid' => $uid,
            'symbol' => $symbol
        ], ["balance" => 0, "balance_lock" => 0]);
        if (!$assert) {
            $this->error(2001);
        }
        return $assert;
    }

    public function getBalance($uid, $symbol)
    {
        $assert = $this->getModel()->newQuery()
            ->where('uid', $uid)
            ->where('symbol', $symbol)
            ->first();
        if (!$assert) {
            $this->error(2001);
        }
        return $assert->balance ?: 0;
    }

    public function updateBalance($uid, $symbol, $amount, $balance_name, $type = 0)
    {
        if ($amount == 0) {
            return true; //金额0直接返回true
        }

        if ($type == ASSET_DEPOSITS || $type == ASSET_DEPOSITS_SYS) {
            $data = array($amount, $amount, $uid, $symbol, $amount);
            $result = DB::update('update ' . $this->table . " set {$balance_name}={$balance_name}+?,deposit_history=deposit_history+? where uid = ? and symbol = ? and {$balance_name}+? >=0 limit 1", $data);
        } else {
            $data = array($amount, $uid, $symbol, $amount);
            $result = DB::update('update ' . $this->table . " set {$balance_name}={$balance_name}+? where uid = ? and symbol = ? and {$balance_name}+? >=0 limit 1", $data);
        }

        if ($result > 0) {
            return true;
        }
        return false;
    }

    public function assetChange($uid, $symbol, $amount, $type, $relate_sn = "", $balance_type = BALANCE_USABLE, $rid = 0)
    {
        $amount = asMoney($amount, 8);
        $balance_name = 'balance_amount';
        switch ($balance_type) {
            case BALANCE_USABLE:
                break;
            case BALANCE_PREPAY:
                $balance_name = "prepare_balance";
                break;
        }
        $result = $this->updateBalance($uid, $symbol, $amount, $balance_name, $type);
        $this->refresh();
        if ($result && $amount != 0) {
            $AssetLogModel = new AssetLog();
            $result = $AssetLogModel->log($uid, $amount, $this->$balance_name, $type, $relate_sn, $symbol, $balance_type, $rid);
        }
        return $result;
    }

    public function detail($data)
    {
        $result = $this->getModel()->newQuery()
            ->where('symbol', $data['symbol'])
            ->select("symbol", "balance", "balance_lock", "created_at")
            ->first();

        if ($result) {
            $result['balance'] = apiNewMoney($result['balance'], 4);
            $result['balance_lock'] = apiNewMoney($result['balance_lock'], 4);
        }
        return $result;
    }

    /**
     * @param $uid
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null|UserAsset
     * @throws ApiException
     */
    public static function getContractAccount($uid)
    {
        $wallet = UserAsset::query()->where('uid', $uid)->first();
        if (blank($wallet)) throw new ApiException('账户类型错误');
        return $wallet;
    }

    /**
     * @return string
     */
    public function getBalanceUnusableAttribute()
    {
        $return = bcadd($this->balance_lock, $this->used_balance);
        $return = bcadd($return, $this->freeze_balance);
        $return = bcadd($return, $this->freeze_all);

        return $return;
    }

}
